/*	MechAttack class definition.
 *
*/

#include "MechAttack.h"

MechAttack::MechAttack(std::string incName) : Behavior(incName)
{
	
}

void MechAttack::Enter()
{
	DEBUG_PRINT("MechAttack(%p) entering.\n", this);
}

void MechAttack::Execute()
{
	BWAPI::Position attackPosition(BB->GetAttackPosition());

	//std::list<BWAPI::Unit*>* vultures = BB->GetUnitsByTypeGeneral(BWAPI::UnitTypes::Terran_Vulture);
	std::list<BWAPI::Unit*>* tanks = BB->GetUnitsByTypeGeneral(BWAPI::UnitTypes::Terran_Siege_Tank_Tank_Mode);
	std::list<BWAPI::Unit*>* goliaths = BB->GetUnitsByTypeGeneral(BWAPI::UnitTypes::Terran_Goliath);
	//if(vultures || tanks || goliaths)
	if( tanks || goliaths)
	{	
		// Tell bioball army to attackmove
		std::list<BWAPI::Unit*> groundArmy;
		//if(vultures)
			//groundArmy.insert(groundArmy.end(), vultures->begin(), vultures->end());
		if(tanks)
			groundArmy.insert(groundArmy.end(), tanks->begin(), tanks->end());
		if(goliaths)
			groundArmy.insert(groundArmy.end(), goliaths->begin(), goliaths->end());
		for(std::list<BWAPI::Unit*>::iterator it = groundArmy.begin(); it != groundArmy.end(); it++)
		{
			if((*it)->getRemainingBuildTime()>0)
				continue;
			BWAPI::Unit* theUnit = (*it);
			theUnit->attack(attackPosition,true);
			if(theUnit->getType() == BWAPI::UnitTypes::Terran_Siege_Tank_Tank_Mode && findNearestEnemy(theUnit))
			{

				theUnit->siege();
				theUnit->attack(findNearestEnemy(theUnit),true);

			}
			if(theUnit->getType() == BWAPI::UnitTypes::Terran_Siege_Tank_Siege_Mode && !findNearestEnemy(theUnit))
			{

				theUnit->unsiege();
				theUnit->attack(attackPosition,true);
			}
			theUnit->attack(attackPosition,true);

		}
	}

	// control cleanup
	control->FinishWithSuccess();

}

void MechAttack::Exit()
{
	DEBUG_PRINT("Exiting MechAttack behavior.\n");
}

bool MechAttack::CheckConditions()
{
	//std::list<BWAPI::Unit*>* vultures = BB->GetUnitsByTypeGeneral(BWAPI::UnitTypes::Terran_Vulture);
	std::list<BWAPI::Unit*>* tanks = BB->GetUnitsByTypeGeneral(BWAPI::UnitTypes::Terran_Siege_Tank_Tank_Mode);
	std::list<BWAPI::Unit*>* goliaths = BB->GetUnitsByTypeGeneral(BWAPI::UnitTypes::Terran_Goliath);
	int totalSize = 0;
	//if(vultures)
		//totalSize += vultures->size();
	if(tanks)
		totalSize += tanks->size();
	if(goliaths)
		totalSize += goliaths->size();

	if(totalSize < 3)
		return false;
	else
		return true;
}

BWAPI::Unit* MechAttack::findNearestEnemy(BWAPI::Unit* myVulture)
{
	BWAPI::Unit* currentBest = 0;
	BWAPI::Position myPos = myVulture->getPosition(), closePos;
	double bestDist=-1;
	for(std::set<BWAPI::Unit*>::const_iterator i=BWAPI::Broodwar->getAllUnits().begin();i!=BWAPI::Broodwar->getAllUnits().end();i++)
	{
		if(!(*i) || !(*i)->exists())
			continue;
		if ((*i)->getPlayer()->isEnemy(myVulture->getPlayer()))
		{
			BWAPI::Position testPos = (*i)->getPosition();
			double d = testPos.getDistance(myPos);
			if(!currentBest) {
				currentBest = (*i);
				bestDist = d;
			}
			else {
				if(d<bestDist) {
					currentBest = (*i);
					bestDist = d;
				}
			}
		}
	}
	if(currentBest) {
		//BWAPI::Broodwar->sendText("Nearest enemy: %s", currentBest->getType().getName().c_str());
	}
	else {
		//BWAPI::Broodwar->sendText("No nearest enemy");
	}
	return currentBest;
}